#include <thread>
#include <atomic>
#include <cassert>
#include <iostream>

void writes_ordering() {
    std::atomic<bool> x(false);
    std::atomic<bool> y(false);
    std::atomic<int> cnt(0);

    std::thread read_x_then_y(
        [&]() {
            while (!x.load(std::memory_order_relaxed)) {}
            if (!y.load(std::memory_order_relaxed)) {
                // x = 1, y = 0
                ++cnt;
            }
        }
    );

    std::thread read_y_then_x(
        [&]() {
            while (!y.load(std::memory_order_relaxed)) {}
            if (!x.load(std::memory_order_relaxed)) {
                // y = 1, x = 0
                ++cnt;
            }
        }
    );

    std::thread write_x(
        [&]() {
            x.store(true, std::memory_order_relaxed);
        }
    );

    std::thread write_y(
        [&]() {
            y.store(true, std::memory_order_relaxed);
        }
    );

    write_x.join();
    write_y.join();
    read_x_then_y.join();
    read_y_then_x.join();

    std::cout << cnt << std::endl;
    assert(cnt <= 1);

}

int main() {
    for (size_t i = 0; i < 100000; ++i) {
        writes_ordering();
    }
    return 0;
};
